package cn.signalpha.modules.shop.service;

import cn.signalpha.common.constant.MsgConstant;
import cn.signalpha.common.utils.Arith;
import cn.signalpha.common.utils.Assert;
import cn.signalpha.core.log.exception.ServiceException;
import cn.signalpha.core.redis.cache.RedisCache;
import cn.signalpha.core.tool.jackson.JsonUtil;
import cn.signalpha.core.tool.support.Kv;
import cn.signalpha.core.tool.utils.CollectionUtil;
import cn.signalpha.core.tool.utils.ObjectUtil;
import cn.signalpha.core.tool.utils.StringPool;
import cn.signalpha.core.tool.utils.StringUtil;
import cn.signalpha.modules.com.service.UserService;
import cn.signalpha.modules.shop.dto.CartDTO;
import cn.signalpha.modules.shop.entity.Cart;
import cn.signalpha.modules.shop.entity.Goods;
import cn.signalpha.modules.shop.entity.GoodsSku;
import cn.signalpha.modules.shop.entity.Seller;
import cn.signalpha.modules.shop.event.SellerCartEvent;
import cn.signalpha.modules.shop.mapper.CartMapper;
import cn.signalpha.modules.shop.vo.*;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 购物车 服务类
 *
 * @author suguangjun
 */
@Service
@AllArgsConstructor
public class CartService extends ServiceImpl<CartMapper, Cart> {

	private final RedisCache redisCache;
	private final UserService userService;
    private final GoodsService goodsService;
	private final SellerService sellerService;
    private final GoodsSkuService goodsSkuService;
	private final ApplicationContext applicationContext;
	private final SellerAddressService sellerAddressService;

	/**
	 * 根据商品id删除购物车
	 */
	public void removeByGoodsId(Serializable goodsId) {
		this.baseMapper.delete(Wrappers.<Cart>lambdaQuery().eq(Cart::getGoodsId, goodsId));
	}

    /**
     * 根据用户id找购物车商品
     */
    public List<OrderConfirmVO.SellerCartItemVO> getSellerCartItemList(Map<String, Object> params) {
        List<OrderConfirmVO.SellerCartItemVO> shopCartItemDtoList = baseMapper.selectCartItemByUserId(params);
        for (OrderConfirmVO.SellerCartItemVO sellerCartItemVO : shopCartItemDtoList) {
			sellerCartItemVO.setDeductMoney(0d);
			sellerCartItemVO.setDeductIntegral(0d);
			sellerCartItemVO.setDeductIntegralMoney(0d);
			sellerCartItemVO.setDeductCouponSeller(0d);
			sellerCartItemVO.setDeductCouponSystem(0d);
			sellerCartItemVO.setDeductPublicity(0d);
			sellerCartItemVO.setDeductPublicityType(StringPool.EMPTY);
			sellerCartItemVO.setGoodsTotalPrice(Arith.mul(sellerCartItemVO.getGoodsNum(), sellerCartItemVO.getGoodsPrice()));
			sellerCartItemVO.setOrderPrice(sellerCartItemVO.getGoodsTotalPrice());
		}
        return shopCartItemDtoList;
    }

    /**
     * 根据商户组装购物车中的商品信息
     */
    public List<CartVO> getShopCarts(List<OrderConfirmVO.SellerCartItemVO> cartItems) {
        // 根据商户ID划分item
        Map<Long, List<OrderConfirmVO.SellerCartItemVO>> sellerCartMap = cartItems.stream().collect(Collectors.groupingBy(OrderConfirmVO.SellerCartItemVO::getSellerId));

        //返回一个商户的所有信息
        List<CartVO> cartVOList = new ArrayList<>();
        for (Long sellerId : sellerCartMap.keySet()) {
            //获取商户的所有商品项
            List<OrderConfirmVO.SellerCartItemVO> sellerCartItemList = sellerCartMap.get(sellerId);

			Seller seller = sellerService.getById(sellerId);
			if(ObjectUtil.isEmpty(seller)){
				throw new ServiceException("未查询到商户信息");
			}

            //构建每个商户的购物车信息
			CartVO cartVO = new CartVO();
			cartVO.setSellerId(seller.getId());
			cartVO.setSellerName(seller.getName());
			cartVO.setSellerLogo(seller.getLogo());
			cartVO.setSellerIsOpenPick(seller.getIsOpenPick());
			if(seller.getIsOpenPick() == 1){
				List<SellerPickConfigVO> sellerPickConfigList = JsonUtil.parseArray(seller.getPickConfig(), SellerPickConfigVO.class);
				sellerPickConfigList.forEach(pickConfigVO -> {
					pickConfigVO.setAddress(sellerAddressService.getById(pickConfigVO.getAddressId()));
				});
				cartVO.setSellerPickConfigList(sellerPickConfigList);
			}
			cartVO.setSellerIsOpenDelivery(seller.getIsOpenDelivery());
			if(seller.getIsOpenDelivery() == 1){
				cartVO.setSellerDeliveryConfig(JsonUtil.parse(seller.getDeliveryConfig(), SellerDeliveryConfigVO.class));
			}
			cartVO.setSellerExt(JsonUtil.parse(seller.getExt(), SellerExtVO.class));
			applicationContext.publishEvent(new SellerCartEvent(cartVO, sellerCartItemList));
            cartVOList.add(cartVO);
        }
        return cartVOList;
    }

    /**
     * 添加商品到购物车
     */
    public Long addGoodsToCart(CartDTO.SaveDTO saveDTO, Long userId) {
		Goods goods = goodsService.getById(saveDTO.getGoodsId());
		Assert.isNull(goods, MsgConstant.OBJECT_NULL);

    	//校验商品是否可以购买
        this.verifyGoodsIsCanBuy(saveDTO.getGoodsId(), saveDTO.getGoodsNum(), saveDTO.getGoodsSkuId());

		//购物车是否有此商品，有的话直接覆盖，不在基础上增加
		Cart cart = getOne(Wrappers.<Cart>lambdaQuery().eq(Cart::getUserId, userId)
			.eq(Cart::getGoodsId, saveDTO.getGoodsId()).eq(Cart::getGoodsSkuId, saveDTO.getGoodsSkuId())
		);
		if(ObjectUtil.isNotEmpty(cart)){
			updateById(Cart.builder().id(cart.getId()).goodsNum(cart.getGoodsNum() + saveDTO.getGoodsNum()).build());
			return cart.getId();
		}

        Cart cartSave = new Cart();
        cartSave.setUserId(userId);
        cartSave.setSellerId(goods.getSellerId());
        cartSave.setGoodsId(goods.getId());
		cartSave.setGoodsType(goods.getType());
        cartSave.setGoodsNum(saveDTO.getGoodsNum());
        cartSave.setGoodsSkuId(saveDTO.getGoodsSkuId());
        cartSave.setStatus(1);
        cartSave.setCreateTime(new Date());
        this.save(cartSave);
        return cartSave.getId();
    }

    /**
     * 组装用户提交的购物车商品项
     */
    public List<OrderConfirmVO.SellerCartItemVO> getSellerCartItemList(CartDTO.SaveDTO orderItem, List<Long> cartIds, Long userId) {
        if (orderItem == null && CollectionUtil.isEmpty(cartIds)) {
            return Collections.emptyList();
        }

        //当立即购买时，没有提交的订单是没有购物车信息的
        if (CollectionUtil.isEmpty(cartIds) && orderItem != null) {
            this.verifyGoodsIsCanBuy(orderItem.getGoodsId(), orderItem.getGoodsNum(), orderItem.getGoodsSkuId());
			Goods goods = goodsService.getById(orderItem.getGoodsId());
			GoodsSku goodsSku = goodsSkuService.getById(orderItem.getGoodsSkuId());
			OrderConfirmVO.SellerCartItemVO sellerCartItemVO = new OrderConfirmVO.SellerCartItemVO();
			sellerCartItemVO.setId(-1L);
			sellerCartItemVO.setSellerId(goods.getSellerId());
			sellerCartItemVO.setGoodsId(orderItem.getGoodsId());
			sellerCartItemVO.setGoodsName(goods.getName());
			sellerCartItemVO.setGoodsType(goods.getType());
			sellerCartItemVO.setGoodsStatus(goods.getStatus());
			sellerCartItemVO.setGoodsImg(StringUtil.isBlank(goodsSku.getImg()) ? goods.getImg() : goodsSku.getImg());
			sellerCartItemVO.setGoodsNum(orderItem.getGoodsNum());
			sellerCartItemVO.setGoodsPrice(goodsSku.getGoodsPrice());
			sellerCartItemVO.setGoodsTotalPrice(Arith.mul(goodsSku.getGoodsPrice(), orderItem.getGoodsNum()));
			sellerCartItemVO.setOrderPrice(sellerCartItemVO.getGoodsTotalPrice());
			sellerCartItemVO.setDeductMoney(0d);
			sellerCartItemVO.setDeductIntegral(0d);
			sellerCartItemVO.setDeductIntegralMoney(0d);
			sellerCartItemVO.setDeductCouponSeller(0d);
			sellerCartItemVO.setDeductCouponSystem(0d);
			sellerCartItemVO.setDeductPublicity(0d);
			sellerCartItemVO.setDeductPublicityType(StringPool.EMPTY);
			sellerCartItemVO.setGoodsSkuId(goodsSku.getId());
			sellerCartItemVO.setGoodsSpec(goodsSku.getSpec());
            return Collections.singletonList(sellerCartItemVO);
        }
        return getSellerCartItemList(Kv.create().set("userId", userId.toString())).stream().filter(item -> cartIds.contains(item.getId())).collect(Collectors.toList());
    }

    /**
     * 校验商品是否可以购买
     */
    private void verifyGoodsIsCanBuy(Long goodsId, Integer goodsNum, Long goodsSkuId) {
        Goods goods = goodsService.getById(goodsId);
        Assert.isNull(goods, "商品不存在");
        if(goods.getStatus() == 0){
            throw new ServiceException("商品已下架");
        }

		GoodsSku goodsSku = goodsSkuService.getById(goodsSkuId);
		Assert.isNull(goodsSku, "请选择正确的规格");
		//避免用其他商品规格
		if(!goodsSku.getGoodsId().equals(goods.getId())){
			throw new ServiceException("请选择正确的规格");
		}
		if(goodsNum > goodsSku.getStock()){
			throw new ServiceException("库存不足");
		}
    }

}
